from flask import Blueprint, request, session, jsonify, current_app
from models.blog import BlogModel
from models.img import ImageModel
from models.starlist import StarListModel
from models.comment import CommentModel
from datetime import datetime
from utils import restful
from .images import delete_img_delete,delete_img_update
from hooks import login_auth

from exts import db


bp = Blueprint("blog", __name__, url_prefix="/blog")

# 1、单个博客详细信息
@bp.route('/get/<int:blog_id>', methods=['GET'])
def get_blog(blog_id):
    """
    获取博客详情
    :param blog_id: 博客id
    :return:
    """
    res = {}
    # 1、获取博客信息
    blog = BlogModel.query.get(blog_id)
    if blog:
        res = blog.to_dict()
        res['author'] = blog.author.username
        res['avatar'] = blog.author.avatar
        # 2、获取用户对该博客的收藏状态
        res['is_stared'] = False  # 未收藏
        res['is_author'] = False  # 非作者
        open_id = session.get('open_id')
        if open_id:
            # 是否为博客作者
            if open_id == blog.blog_author_id:
                res['is_author'] = True
            # 是否收藏
            s = StarListModel.query.filter(StarListModel.star_user_id==open_id,StarListModel.star_blog_id==blog_id).one_or_none()
            if s:
                res['is_stared'] = True  # 已收藏
    else:
        return restful.params_error(message='博客id不存在')
    return restful.ok(message='请求成功', data={'blog':res})


# 2、分页数据-
@bp.route('/getPage/<int:last_time>', methods=['GET'])
def get_blogs(last_time):
    # 1、获取分页数据
    blogs = get_blog_page(last_time//1000,True)
    # 2、将结果转换为json
    res = {}
    bs = []
    for blog in blogs:
        tmp = blog.to_dict(choice='simple')
        tmp['author'] = blog.author.username
        tmp['avatar'] = blog.author.avatar
        bs.append(tmp)
    res['blogs'] = bs
    return restful.ok(data=res)


# 3、新增博客
@bp.route('/create', methods=['POST'])
@login_auth
def create_blog():
    # 1、获取前端json数据
    data = request.json
    print(data)
    open_id = session.get('open_id')
    # 2、更新数据库 BlogModel、ImageModel
    blog = BlogModel(blog_author_id=open_id, title=data.get('title'), content=data.get('content'), create_time=datetime.now(),update_time=datetime.now())
    if(data.get('cover_img')):
        blog.cover_img = data.get('cover_img')
    db.session.add(blog)
    db.session.flush()
    images = []
    if(data.get('imgs')):
        for u in data.get('imgs'):
            if u:
                image = ImageModel(article_id=blog.blog_id,type='blog',url=u)
                images.append(image)
    db.session.add_all(images)
    db.session.commit()
    return restful.ok(message='上传成功',data=str(blog.blog_id))


# 4、更新博客内容
@bp.route('/update/<int:blog_id>', methods=['POST','PUT'])
@login_auth
def update_blog(blog_id):
    data = request.json
    data['blog_id'] = blog_id
    print(data)
    # 1、获取原有 old_blog对象
    old_blog = BlogModel.query.get(blog_id)
    # 2、修改原有blog对象值
    if(old_blog):
        # 2.1、修改 旧blog信息
        old_blog.title = data.get('title') if data.get('title') else old_blog.title
        old_blog.content = data.get('content') if data.get('content') else old_blog.content
        old_blog.cover_img = data.get('cover_img') if data.get('cover_img') else old_blog.cover_img
        old_blog.update_time = datetime.now()
        old_blog.allow_publish = 2 # 恢复到待审核状态
        old_blog.review = ''
        db.session.commit()
        # 2.2、删除图片，数据库和文件，调用 images.delete_img_update
        delete_img_update(blog_id, 'blog', data.get('imgs'), data.get('imgList'))
    else:
        return restful.params_error()
    return restful.ok(message="上传成功",data=str(blog_id))

# 5、删除博客
@bp.route('/delete/<int:blog_id>', methods=['DELETE'])
@login_auth
def delete_blog(blog_id):
    # 1、删除blog
    old_blog = BlogModel.query.get(blog_id)
    # 2、删除图片
    delete_img_delete(blog_id,'blog')
    # 3、删除评论
    CommentModel.query.filter(CommentModel.comment_blog_id==blog_id).delete(synchronize_session=False)
    # 4、删除收藏列表
    StarListModel.query.filter(StarListModel.star_blog_id==blog_id).delete(synchronize_session=False)
    # 5、提交事务
    db.session.delete(old_blog)
    db.session.commit()
    return restful.ok(message='删除成功')

# 6、根据作者获取用户博客-
@bp.route('/getByAuthor/<int:last_time>', methods=['GET'])
@login_auth
def get_by_author(last_time):
    open_id = session.get('open_id')
    page_size = current_app.config['BLOG_PAGE_SIZE']
    res = {}
    bs = []
    last_time = datetime.fromtimestamp(last_time//1000)
    if open_id:
        query = BlogModel.query\
            .filter(BlogModel.blog_author_id==open_id, BlogModel.update_time<last_time)\
            .order_by(BlogModel.update_time.desc())
        blogs = query.limit(page_size).all()
        for blog in blogs:
            bs.append(blog.to_dict(choice='admin'))
    else:
        return restful.unlogin_error()
    res['blogs']=bs
    return restful.ok(message="请求成功!", data=res)


# 7、博客审核
@bp.route('/check/<int:blog_id>', methods=['POST'])
@login_auth
def check_blog(blog_id):
    data = request.json
    print(data)
    blog = BlogModel.query.get(blog_id)
    allow_publish = data.get('allow_publish')
    review = data.get('review')
    if allow_publish!=None and review!=None:
        blog.allow_publish = allow_publish
        blog.review = review
        db.session.commit()
    return restful.ok(message='审核成功')


# 8、管理员获取所有博客
@bp.route('/getAdmin/<int:last_time>', methods=['GET'])
@login_auth
def get_blogs_admin(last_time):
    # 1、获取分页数据
    blogs = get_blog_page(last_time//1000,False)
    # 2、将结果转换为json
    bs = []
    for blog in blogs:
        tmp = blog.to_dict(choice='admin')
        bs.append(tmp)
    return restful.ok(data={'blogs':bs})

# 9、获取未审核的博客数
@bp.route('/getUncheck', methods=['GET'])
@login_auth
def get_check_count():
    c = BlogModel.query.filter_by(allow_publish=2).count()
    return restful.ok(data={'uncheckCount':c})

# 获取分页数据
def get_blog_page(last_time, is_publish):
    page_size = current_app.config['BLOG_PAGE_SIZE']
    # 1、处理时间信息
    last_time = datetime.fromtimestamp(last_time)
    # 2、获取当页数据
    if is_publish: # 是否已过审核
        query = BlogModel.query.filter(BlogModel.allow_publish==1, BlogModel.update_time<last_time).order_by(BlogModel.update_time.desc())
    else:  # 未过审核
        query = BlogModel.query.filter(BlogModel.update_time < last_time).order_by(BlogModel.update_time.desc())
    blogs = query.limit(page_size).all()
    return blogs
